//
//  HomeViewModel.swift
//  memo
//
//  Created by DaleGuo on 2023/10/1.
//

import Combine
import CoreData
import Foundation
import WidgetKit

class HomeViewModel: ObservableObject {
    // 要给widget 所以 share出来
    public static var share = HomeViewModel()
    
    // coredata 配置
    var viewContext = PersistenceController.shared.viewContext
    private let containerName = "memo"
    private let memoName = "MemoEntity"
    // raw data
    @Published var allMemos: [MemoEntity] = []
    
    // 过滤后的数据
    @Published var memos: [MemoEntity] = []
    @Published var trashMemos: [MemoEntity] = []
    @Published var day_todos: [Date: [TodoEntity]] = [:]
    @Published var searchText = ""
    
//    private let memoDateService = MemoDataService.memoDataService
    
    private var cancelables = Set<AnyCancellable>() // 当不需要主动cancel时，就将其存入set中
    
    init() {
        getAllMemos()
        addSubscriber()
    }
    
    func getAllMemos() {
        let request = NSFetchRequest<MemoEntity>(entityName: memoName)
        request.sortDescriptors = [NSSortDescriptor(keyPath: \MemoEntity.updated_date_, ascending: false), NSSortDescriptor(keyPath: \MemoEntity.title_, ascending: true)]

        do {
            allMemos = try viewContext.fetch(request)
//            print("下面是VM中的raw数据：")
//            allMemos.forEach { MemoEntity in
//                MemoEntity.todos.forEach { TodoEntity in
//                    print(TodoEntity.content + "  -  " + TodoEntity.is_completed.description)
//                }
//            }
            
        } catch {
            print("Error fetching entity: \(error)")
        }
    }
    
    func addSubscriber() {
        // 这里过滤了filter del
        $searchText
            .combineLatest($allMemos)
            .debounce(for: .seconds(0.5), scheduler: DispatchQueue.main) // 去抖
            .map(filterDelMemos)
            .sink { [weak self] filteredMemos in
                self?.trashMemos = filteredMemos
            }
            .store(in: &cancelables)
        
        // 这里过滤了filter no_del
        $searchText
            .combineLatest($allMemos)
            .debounce(for: .seconds(0.5), scheduler: DispatchQueue.main) // 去抖
            .map(filterMemos)
            .sink { [weak self] filteredMemos in
                self?.memos = filteredMemos
            }
            .store(in: &cancelables)
        
        // 获取所有todos，直接订阅上面的memos，并改为 day : [todo]
        $memos
            .combineLatest($searchText)
            .debounce(for: .seconds(0.5), scheduler: DispatchQueue.main) // 去抖
            .map(filterTodosInMemos)
            .sink { [weak self] todos in
                self?.day_todos = todos
            }
            .store(in: &cancelables)
    }
    
    private func filterTodosInMemos(memos: [MemoEntity], searchText: String) -> [Date: [TodoEntity]] {
        // memos.mome.todos.todo
        
        let todoss = memos.map { memo in
            memo.todos
        }
        
        var todos = todoss.flatMap { $0 }
        
        if !searchText.isEmpty {
            todos = todos.filter { $0.content.contains(searchText) }
        }
        
        let calendar = Calendar.current
        
        // 转化为 day:[todos]  其中dat 为dateComponents类型,抹平day以下，再转为date 主要为了可排序，然后再view中格式化显示
        let day_todos = Dictionary(grouping: todos) { todo in
            
            let day = calendar.dateComponents([.year, .month, .day], from: todo.updated_date)
            
            // 抹平day以下
            return Calendar.current.date(from: day)!
        }
            
        return day_todos
    }
    
    private func filterMemos(searchText: String, startingMemos: [MemoEntity]) -> [MemoEntity] {
        guard !searchText.isEmpty else {
            return startingMemos.filter { memo -> Bool in
                !memo.del_flag
            }
        }
        
        let filteredMemos = startingMemos.filter { memo -> Bool in
            memo.title.contains(searchText) || memo.content.contains(searchText) || memo.todos.contains(where: { todo in
                todo.content.contains(searchText)
            })
        }
        
        return filteredMemos.filter { memo -> Bool in
            !memo.del_flag
        }
    }
    
    private func filterDelMemos(searchText: String, startingMemos: [MemoEntity]) -> [MemoEntity] {
        guard !searchText.isEmpty else {
            return startingMemos.filter { memo -> Bool in
                memo.del_flag
            }
        }
        
        let filteredMemos = startingMemos.filter { memo -> Bool in
            memo.title.contains(searchText) || memo.content.contains(searchText) || memo.todos.contains(where: { todo in
                todo.content.contains(searchText)
            })
        }
        
        return filteredMemos.filter { memo -> Bool in
            memo.del_flag
        }
    }
    
    func addMemo(title: String = "", content: String = "") {
//        let memo_new = memoDateService.addMemo(title: tilte, content: content) // service中只保存 没有重新请求
//        memos.insert(memo_new, at: 0)
        
        let memoEntity = MemoEntity(context: viewContext)
        
        memoEntity.title = title
        memoEntity.content = content
        memoEntity.updated_date = Date()
        
        save()
        
//        return memoEntity
    }
    
    func addTodo(content: String = "", memo: MemoEntity) {
//        memoDateService.addTodo(content: content, memo: memo)
        
        let todo = TodoEntity(context: viewContext)
        todo.content = content
        todo.updated_date = Date()
        todo.memo = memo
        save()
    }
    
    func todo_toggle(todo: TodoEntity) {
//        memoDateService.updateTodo(todo: todo, content: todo.content, is_completed: !todo.is_completed, level: todo.level)
        
        todo.is_completed.toggle()
        save()
    }
    
    func update_todo(todo: TodoEntity) {
        todo.level.toggle()
        save()
    }
    
    func delete_todo(todo: TodoEntity) {
//        memos.removeAll { rawMemo in
//            rawMemo.id == todo.id
//        }
//        memoDateService.deleteTodo(todo: todo)
        viewContext.delete(todo)
    }
    
    // 回收站
    func deleteMemo_flag(memo: MemoEntity) {
//        memoDateService.toggle_memo_del(memo: memo)
        memo.del_flag.toggle()
        save()
    }
    
    func rollbackMemo(memo: MemoEntity) {
//        memoDateService.toggle_memo_del(memo: memo)
        memo.del_flag.toggle()
        save()
    }
    
    func deleteMemo(memo: MemoEntity) {
        /// 还需要处理 联级删除 todos
//        memoDateService.delete(entity: memo)
        viewContext.delete(memo)
    }
    
    func deleteMemos(memos: [MemoEntity]) {
        memos.forEach { memo in
            viewContext.delete(memo)
            
        }
        save()
        
        
    }
    
    func rollbackMemos(memos: [MemoEntity]) {
//        memoDateService.rollbackMemos(memos: memos)
        memos.forEach { $0.del_flag.toggle() }
        save()
    }
    
    func save() {
        do {
            try viewContext.save()
            getAllMemos()
            
//            print("下面是vm中的filter数据")
//            memos.forEach { MemoEntity in
//                MemoEntity.todos.forEach { TodoEntity in
//                    print(TodoEntity.content + "  -  " + TodoEntity.is_completed.description)
//                }
//            }
            
            WidgetCenter.shared.reloadTimelines(ofKind: "memoWidget")
        } catch {
            print("Error saving data! \(error)")
        }
    }
    
    func applyChange() {
        save()
//        getAllMemos()
    }
    
    // Preview
}
